﻿
namespace Patterns4Net.Tests.Core.CecilExtensions 
{
    using System.Collections.Generic;
    using System.Diagnostics.Contracts;
    using System.Linq;
    using Mono.Cecil;
    using NUnit.Framework;
    using Patterns4Net.Core.CecilExtensions;

    [TestFixture]
    public class ReflectionToCecilTest 
    {
        [Test]
        [Category("Integration")]
        public void Try_Get_Current_Assembly() {
            ModuleDefinition module = this.GetType().Assembly.GetModuleDefinition();

            // We loaded something
            Contract.Assume(module != null);
            Contract.Assume(module.Types != null);

            // It contains this class, so it is indeed current assembly...
            Assert.IsTrue(module.Types.Any(x => x.Name == this.GetType().Name));
        }

        [Test]
        [Category("Integration")]
        public void Try_Get_Current_Class_Type() 
        {
            TypeDefinition typeDefinition = this.GetType().GetTypeDefinition();

            Assert.IsNotNull(typeDefinition);
            Assert.AreEqual(typeDefinition.Name, this.GetType().Name);
        }

        [Test]
        [Category("Integration")]
        public void Try_Get_TypeDefinition_Of_Nested_Class() 
        {
            TypeDefinition typeDefinition = typeof(NestedClass).GetTypeDefinition();
            Assert.IsNotNull(typeDefinition);
            Assert.AreEqual(typeDefinition.Name, typeof(NestedClass).Name);
        }

        [Test]
        public void Try_GetTypeReference_Of_Generic_Type_Instance()
        {
            var result = typeof(Dictionary<int, string>).GetTypeReference();
            Assert.IsNotNull(result);
            Assert.IsTrue(result.FullName.StartsWith("System.Collections.Generic"));
            Assert.AreEqual(2, ((GenericInstanceType)result).GenericArguments.Count);
        }

        [Test]
        public void Try_GetTypeDefinition_Of_Generic_Type()
        {
            var result = typeof(Dictionary<,>).GetTypeDefinition();
            Assert.IsNotNull(result);
            Assert.IsTrue(result.FullName.StartsWith("System.Collections.Generic"));
        }

        [Test]
        public void GetCecilTypeName_Converts_Plush_To_Slash()
        {
            var name = ReflectionToCecil.GetCecilTypeName("Hello.World+Nested");
            Assert.AreEqual("Hello.World/Nested", name);
        }

        /// Just dummy class
        public class NestedClass 
        {   
        }
    }
}